package data;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * Contains information about the netflix data
 * 
 * @author Robert Layton
 * 
 */
public class DataInfo {

	// Numbered from 1 to 17770 inclusive
	public static final int NUM_MOVIES = 17770;

	// Use the function getUsers to get the actual userIDs
	public static final int NUM_USERS = 480189;

	// No index for ratings.
	public static final int NUM_RATINGS = 100480507;

	// Remember to include the trailing '/' character for these
	/**
	 * Location of the folder where the download from Netflix is stored
	 * (training_set folder)
	 */
	public static final String downloadFolder = "/home/bob/projects/netflix/data/";

	private static int[] userIDs = null;

	// Remember to include the trailing '/' character for these
	/**
	 * Location of the binary files
	 */
	public static String binaryFolder = "/home/bob/projects/netflix/binary/";

	/**
	 * Returns an int array containing the indexes of all the users
	 * 
	 * @return int[DataInfo.numUsers] The user IDs of all users
	 */
	public static int[] getAllUserIDs() {
		if (userIDs == null) {
			System.out.print("Loading movie indexed ratings...");
			ObjectInputStream ois = null;
			try {
				String userIndexesFilename = DataInfo.binaryFolder
						+ "userIndexes.data";
				ois = new ObjectInputStream(new FileInputStream(
						userIndexesFilename));
				userIDs = (int[]) ois.readObject();
				ois.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			System.out.println("done");
		}
		return userIDs;
	}

	/**
	 * Checks if a given double is invalid and prints a message to System.err if
	 * it is. Use the label to identify the variable in question.
	 * 
	 * @param label
	 * @param val
	 */
	public static void checkInvalidDouble(String label, double val) {
		if (Double.isInfinite(val) || Double.isNaN(val)) {
			System.err.println(label + " is an invalid double");
		}
	}

	private static int lastUserID = -1;

	private static int lastUI = -1;

	public static int getUserIndex(int userID) {
		if (userID == lastUserID) {
			return lastUI;
		}

		int[] userIDs = DataInfo.getAllUserIDs();
		// Find the index of the userid
		for (int i = 0; i < userIDs.length; i++) {
			if (userIDs[i] == userID) {
				lastUserID = userID;
				lastUI = i;
				return i;
			}
		}
		return -1;
	}

	public static int getUsersID(int userIndex) {
		if (userIDs == null) {
			userIDs = DataInfo.getAllUserIDs();
		}
		return userIDs[userIndex];
	}

}
